﻿using PLCS.App.Shared.Events;
using Prism.Commands;
using Prism.Events;
using Prism.Services.Dialogs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Windows.Input;

using Prism.Ioc;
using PLCS.App.Shared.Extensions;
using PLCS.App.Shared.ViewModels;
using System.Windows;
using PLCS.PlcInteraction.PLCHelper;

namespace PLCS.App.LogManager.ViewModels
{
    public class DebugViewModel : BaseViewModel, IDialogAware
    {
        #region
        public string Title => "调试界面";

        public event Action<IDialogResult> RequestClose;

        public bool CanCloseDialog()
        {
            // throw new NotImplementedException();
            return true;
        }

        public void OnDialogClosed()
        {
            //  throw new NotImplementedException();
        }

        public void OnDialogOpened(IDialogParameters parameters)
        {
            // throw new NotImplementedException();
        }
        public readonly IEventAggregator aggregator;
        public void UpdateLoading(bool IsOpen)
        {
            aggregator.UpdateLoading(new UpdateModel()
            {
                IsOpen = IsOpen
            });
        }
        #endregion
        public ICommand PLCConnect { set; get; }
        public ICommand DBRead { set; get; }
        public ICommand OffsetRead { set; get; }
        public ICommand OffsetWrite { set; get; }
        public DebugViewModel()
        {
            PLCConnect = new DelegateCommand(connectAsync);
            DBRead = new DelegateCommand(dbreadAsync);
            OffsetRead = new DelegateCommand(readoffset);
            OffsetWrite = new DelegateCommand(writeoffset);
            aggregator = ContainerLocator.Container.Resolve<IEventAggregator>();

        }
        private string myVar = "192.168.0.1";

        public string Address
        {
            get { return myVar; }
            set { SetProperty(ref myVar, value); }
        }


        private string myVar3;

        public string Rack
        {
            get { return myVar3; }
            set { SetProperty(ref myVar3, value); }
        }
        private string myVar4;
        public string Slot
        {
            get { return myVar4; }
            set { SetProperty(ref myVar4, value); }
        }

        private string myVar1;

        public string ConnectResult
        {
            get { return myVar1; }
            set { SetProperty(ref myVar1, value); }
        }
        /// <summary>
        /// PLC连接
        /// </summary>
        public async void connectAsync()
        {

            UpdateLoading(true);
            S7Client client = new S7Client();
            try
            {
                string message = "";
                using (Ping ping = new())
                {
                    // 判断网络状态
                    PingReply pingReply = await ping.SendPingAsync(IPAddress.Parse(Address));
                    // 网络不通，则直接结束方法
                    if (pingReply.Status != IPStatus.Success)
                    {
                        message += "网络不通";
                    }
                }

                ConnectResult = message;
                if (!client.Connected)
                {
                    // 尝试连接PLC
                    int result = client.ConnectTo(Address, int.Parse(Rack), int.Parse(Slot));
                    if (result == 0)
                    {
                        //success
                        message += "\r\n" + "PLC连接成功";
                    }
                    else
                    {
                        //faisure
                        message += "\r\n" + "PLC连接失败";
                    }
                }
                ConnectResult = message;
            }
            catch (Exception ex)
            {
                ShowMessage("值不能为空" + ex.ToString());
            }
            finally { UpdateLoading(false); }

        }
        /// <summary>
        /// 属性值
        /// </summary>
        #region
        private int db;

        public int DB
        {
            get { return db; }
            set { SetProperty(ref db, value); }
        }
        private int db1;

        public int DB1
        {
            get { return db1; }
            set { SetProperty(ref db1, value); }
        }
        private int db2;

        public int DB2
        {
            get { return db2; }
            set { SetProperty(ref db2, value); }
        }
        private int ll;

        public int Length
        {
            get { return ll; }
            set { SetProperty(ref ll, value); }
        }
        private string dbcon;

        public string DBContent
        {
            get { return dbcon; }
            set { SetProperty(ref dbcon, value); }
        }

        private string st;

        public string start
        {
            get { return st; }
            set { SetProperty(ref st, value); }
        }
        private string st1;

        public string start1
        {
            get { return st1; }
            set { SetProperty(ref st1, value); }
        }

        private string en;

        public string end
        {
            get { return en; }
            set { SetProperty(ref en, value); }
        }
        private string en2;

        public string OffsetReadContent
        {
            get { return en2; }
            set { SetProperty(ref en2, value); }
        }
        private string en1;

        public string end1
        {
            get { return en1; }
            set { SetProperty(ref en1, value); }
        }
        private string en11;

        public string writevalue
        {
            get { return en11; }
            set { SetProperty(ref en11, value); }
        }
        #endregion
        /// <summary>
        /// 读取db块全部内容
        /// </summary>
        public async void dbreadAsync()
        {

            UpdateLoading(true);
            bool pro = true;
            string yy = "";
            S7Client client = new S7Client();
            try
            {
                #region
                {
                     string message = "";
                    using (Ping ping = new())
                    {
                        // 判断网络状态
                        PingReply pingReply = await ping.SendPingAsync(IPAddress.Parse(Address));
                        // 网络不通，则直接结束方法
                        if (pingReply.Status != IPStatus.Success)
                        {
                            message += "网络不通";
                            pro = false;
                        }
                    }

                    yy = message;
                    if (!client.Connected)
                    {
                        // 尝试连接PLC
                        int result = client.ConnectTo(Address, int.Parse(Rack), int.Parse(Slot));
                        if (result == 0)
                        {
                            //success
                            message = "\r\n" + "PLC连接成功";
                        }
                        else
                        {
                            var res = client.ErrorText(result);
                            //faisure
                            message = "\r\n" + "PLC连接失败:" + res;
                            pro = false;
                        }
                    }
                    yy = message;

                }
                #endregion
                int read = 0;
                if (pro )
                {
                    List<int> Readdata = new List<int>();
                    byte[] buffer = new byte[Length*4];
                    read = client.DBRead(DB, 0, Length *4, buffer);
                    if (read == 0)//读取数据正常
                    {
                        for (int i = 0; i < Length * 4; i += 4)
                        {
                            Readdata.Add(S7.GetDIntAt(buffer, i));
                        }
                        string data = "";
                        int count = 0;
                        foreach (var item in Readdata)
                        {
                            count++;

                            data += count.ToString() + "位:    " + item.ToString() + ";" + "\r\n";

                        }
                        DBContent = data;//读取到的数据绑定到界面
                    }
                    else
                    {
                        DBContent= client.ErrorText(read);//读取异常错误码显示
                    }
                   
                }
                else
                {
                    DBContent = yy;
                }
            }
            catch (Exception ex)
            {
                ShowMessage("值不能为空" + ex.ToString());

            }
            finally
            {
                
                UpdateLoading(false);
            }

        }
        /// <summary>
        /// 偏移量读取
        /// </summary>
        public void readoffset()
        {
            UpdateLoading(true);

            S7Client client = new S7Client();
            int result = client.ConnectTo(Address, int.Parse(Rack), int.Parse(Slot));
            try
            {
                byte[] buffer = new byte[int.Parse(end) *4];
                int read = client.DBRead(DB1, int.Parse(start)*4, int.Parse(end)*4, buffer);
                if (read == 0)
                {
                    List<int> Readdata = new List<int>();
                    for (int i = 0; i < int.Parse(end) * (4-1); i += 4)
                    {
                        Readdata.Add(S7.GetDIntAt(buffer, i));
                    }
                    string data = "";
                    int count = 0;
                    foreach (var item in Readdata)
                    {
                        count++;

                        data += (count).ToString() + "位:    " + item.ToString() + ";" + "\r\n";

                    }
                    OffsetReadContent = data;
                }
                else
                {
                    OffsetReadContent= client.ErrorText(read);
                }
                
            }
            catch (Exception ex)
            {
                ShowMessage("值不能为空" + ex.ToString());
            }
            finally
            {
                UpdateLoading(false);
            }

        }
        /// <summary>
        /// 偏移量写入
        /// </summary>
        public void writeoffset()
        {
            UpdateLoading(true);
            S7Client client = new S7Client();
            try
            {
                
                int ll = int.Parse(end1);
                byte[][] bytes = new byte[ll][];
                string mess = writevalue;

                string[] strings = mess.Split(",");//英文逗号
                if (strings.Count() !=int.Parse(end1))
                {
                    MessageBox.Show("输入数量错误");
                    UpdateLoading(false);
                    return;
                }
                for (int i = 0; i < ll; i++)
                {
                    S7.SetDIntAt(bytes[i], i, int.Parse(strings[i]));
                }

               int write= WritePLCData(4*(int.Parse(start1)-1), bytes, DB2);
                if (write != 0) 
                {
                    MessageBox.Show(client.ErrorText(write).ToString());
                }
            }
            catch (Exception ex)
            {
                ShowMessage("值不能为空" + ex.ToString());

            }
            finally
            {
                UpdateLoading(false);
            }
        }
        #region
        private int WritePLCData(int offset, byte[][] fieldBytes, int dbNumber)
        {


            S7Client ExcuteTask_Write = new S7Client();
            var res = 0;
            for (var i = 0; i < fieldBytes.Length; i++)
            {
                var fieldByte = fieldBytes[i];
                if (fieldByte.Length > 0)
                {
                    res = ExcuteTask_Write.DBWrite(dbNumber, offset + i, fieldByte.Length, fieldByte);
                    if (res != 0) break;
                }
            }
            return res;
        }
        #endregion
    }
}
